using System;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using Windows.Storage.Pickers;
using Windows.Storage;
using Microsoft.UI.Xaml.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using GoChat_for_Windows.Models;
using GoChat_for_Windows.Services;
using GoChat_for_Windows.Views;
using WinRT.Interop;
using System.Linq;

namespace GoChat_for_Windows.ViewModels
{
    public partial class ChatViewModel : ViewModelBase
    {
        private readonly ILocalStorageService _localStorageService;
        private readonly INavigationService _navigationService;
        private readonly UdpService _udpService;
        private CancellationTokenSource? _messagePollingCancellation;
        private readonly Microsoft.UI.Dispatching.DispatcherQueue dispatcherQueue;

        [ObservableProperty]
        private User? currentUser;

        [ObservableProperty]
        private User? targetUser;

        [ObservableProperty]
        private string messageText = string.Empty;

        [ObservableProperty]
        private ObservableCollection<Message> messages = new();

        [ObservableProperty]
        private bool isLoadingMore;

        private int currentPage = 1;
        private const int PageSize = 20;

        public ChatViewModel(
            IApiService apiService,
            ILocalStorageService localStorageService,
            INavigationService navigationService,
            UdpService udpService) : base(apiService)
        {
            _localStorageService = localStorageService;
            _navigationService = navigationService;
            _udpService = udpService;
            dispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread();

            // 订阅消息接收
            _udpService.MessageReceived += (s, message) =>
            {
                dispatcherQueue.TryEnqueue(() =>
                {
                    // 只处理当前聊天对象的消息
                    if (message.SenderId == TargetUser?.Id || message.ReceiverId == TargetUser?.Id)
                    {
                        HandleReceivedMessage(message);
                    }
                });
            };
        }

        private void HandleReceivedMessage(Message message)
        {
            try
            {
                // 如果是普通消息类型,添加到消息列表
                if (message.MessageType != MessageType.Heartbeat && 
                    message.MessageType != MessageType.HeartbeatAck)
                {
                    if (!Messages.Contains(message))
                    {
                        Messages.Add(message);
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorMessage = "处理消息失败: " + ex.Message;
            }
        }

        [RelayCommand]
        private async Task NavigateBackAsync()
        {
            StopMessagePolling();
            _navigationService.GoBack();
            await Task.CompletedTask; // 避免 CS1998 警告
        }

        public async Task InitializeAsync(User target)
        {
            ArgumentNullException.ThrowIfNull(target, nameof(target));
            
            try
            {
                IsBusy = true;
                ClearError();

                TargetUser = target;
                CurrentUser = await _localStorageService.GetUserAsync();

                if (CurrentUser == null)
                {
                    _navigationService.Navigate(typeof(LoginPage));
                    return;
                }

                await LoadMessagesAsync();
                StartMessagePolling();
            }
            catch (Exception ex)
            {
                ErrorMessage = "初始化失败: " + ex.Message;
            }
            finally
            {
                IsBusy = false;
            }
        }

        [RelayCommand]
        private async Task LoadMoreMessagesAsync()
        {
            if (CurrentUser == null || TargetUser == null) return;

            try
            {
                IsLoadingMore = true;
                currentPage++;
                await LoadMessagesAsync();
            }
            finally
            {
                IsLoadingMore = false;
            }
        }

        private async Task LoadMessagesAsync()
        {
            if (CurrentUser == null || TargetUser == null) return;

            try
            {
                var messages = await ApiService.GetMessageHistoryAsync(
                    CurrentUser.Id,
                    TargetUser.Id,
                    PageSize,
                    currentPage);

                foreach (var message in messages.OrderByDescending(m => m.SendTime))
                {
                    if (!Messages.Contains(message))
                    {
                        Messages.Insert(0, message);
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorMessage = "加载消息失败: " + ex.Message;
            }
        }

        [RelayCommand]
        private async Task SendMessageAsync()
        {
            if (string.IsNullOrWhiteSpace(MessageText)) return;
            
            ArgumentNullException.ThrowIfNull(CurrentUser, nameof(CurrentUser));
            ArgumentNullException.ThrowIfNull(TargetUser, nameof(TargetUser));

            try
            {
                var message = new Message
                {
                    SenderId = CurrentUser.Id,
                    ReceiverId = TargetUser.Id,
                    Content = MessageText.Trim(),
                    MessageType = MessageType.Text,
                    SendTime = DateTime.Now,
                    IsSending = true,
                    Sender = CurrentUser,
                    Receiver = TargetUser
                };

                // 先添加到消息列表
                Messages.Add(message);
                MessageText = string.Empty;

                // 发送消息
                var success = await _udpService.SendMessageAsync(message);
                if (!success)
                {
                    message.SendFailed = true;
                    ErrorMessage = "发送消息失败,请重试";
                }
                else
                {
                    message.IsSending = false;
                    // 保存到服务器
                    await ApiService.SendMessageAsync(message);
                }
            }
            catch (Exception ex)
            {
                ErrorMessage = "发送消息失败: " + ex.Message;
            }
        }

        [RelayCommand]
        private async Task SendFileAsync()
        {
            if (CurrentUser == null || TargetUser == null) return;

            try
            {
                var picker = new FileOpenPicker();
                picker.FileTypeFilter.Add("*");

                // 获取当前窗口句柄
                var window = App.Current.GetWindow();
                if (window != null)
                {
                    // 初始化文件选择器
                    InitializeWithWindow.Initialize(picker, WindowNative.GetWindowHandle(window));

                    var file = await picker.PickSingleFileAsync();
                    if (file != null)
                    {
                        var properties = await file.GetBasicPropertiesAsync();
                        
                        var message = new Message
                        {
                            SenderId = CurrentUser.Id,
                            ReceiverId = TargetUser.Id,
                            MessageType = MessageType.File,
                            SendTime = DateTime.Now,
                            IsSending = true,
                            Sender = CurrentUser,
                            Receiver = TargetUser,
                            FileName = file.Name,
                            FileSize = (long)properties.Size
                        };

                        Messages.Add(message);

                        var fileUrl = await ApiService.UploadFileAsync(file.Path, file.ContentType);
                        message.FileUrl = fileUrl;
                        message.Content = $"文件：{file.Name}";
                        
                        var success = await ApiService.SendMessageAsync(message);
                        if (!success)
                        {
                            message.SendFailed = true;
                            ErrorMessage = "发送文件失败";
                        }
                        else
                        {
                            message.IsSending = false;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorMessage = "发送文件失败：" + ex.Message;
            }
        }

        private void StartMessagePolling()
        {
            StopMessagePolling();
            _messagePollingCancellation = new CancellationTokenSource();

            _ = Task.Run(async () =>
            {
                try
                {
                    while (!_messagePollingCancellation.Token.IsCancellationRequested)
                    {
                        if (CurrentUser != null && TargetUser != null)
                        {
                            var latestMessages = await ApiService.GetMessageHistoryAsync(
                                CurrentUser.Id,
                                TargetUser.Id,
                                10,
                                1);

                            foreach (var message in latestMessages.OrderBy(m => m.SendTime))
                            {
                                if (!Messages.Contains(message))
                                {
                                    dispatcherQueue.TryEnqueue(() =>
                                    {
                                        Messages.Add(message);
                                    });
                                }
                            }
                        }

                        await Task.Delay(2000, _messagePollingCancellation.Token); // 每2秒轮询一次
                    }
                }
                catch (TaskCanceledException)
                {
                    // 正常取消,不处理
                }
                catch (Exception ex)
                {
                    // 轮询失败,记录错误但继续尝试
                    ErrorMessage = "消息轮询失败: " + ex.Message;
                }
            }, _messagePollingCancellation.Token);
        }

        private void StopMessagePolling()
        {
            try
            {
                if (_messagePollingCancellation != null)
                {
                    _messagePollingCancellation.Cancel();
                    _messagePollingCancellation.Dispose();
                    _messagePollingCancellation = null;
                }
            }
            catch
            {
                // 忽略取消过程中的任何错误
            }
        }

        public void Cleanup()
        {
            StopMessagePolling();
        }
    }
} 